function CalendarViewHeader(dom, repository, calendarHeaderStatus) {
    this._dom = dom;
    this._container = $('<div/>');
    this._repository = repository;
    this._headerStatus = calendarHeaderStatus;
    this._headerStatusChangeCallback = function() {
    };
}

CalendarViewHeader.prototype = {
    show: function() {
        var visibleMonthModels = this._getVisibleMonthModels();
        this._updateDom(visibleMonthModels);
        this._updateMonthStatus(visibleMonthModels);
        this._headerStatusChangeCallback();
    },

    updateMonthStatus: function() {
        var visibleMonthModels = this._getVisibleMonthModels();
        this._updateMonthStatus(visibleMonthModels);
    },

    getHeaderStatus: function() {
        return this._headerStatus;
    },

    onHeaderStatusChange: function(callback) {
        this._headerStatusChangeCallback = callback;
    },

    _getVisibleMonthModels: function() {
        var me = this;
        var yearMonths = this._headerStatus.getYearMonthsInRange();
        var visibleMonthModels = yearMonths.select(function(yearMonth) {
            return me._repository.getMonthByYearMonth(yearMonth)
        });
        return visibleMonthModels;
    },

    _updateDom: function(visibleMonths) {
        var container = $('<div/>');
        container.append(this._createPreviousYearButton());
        container.append(this._createPreviousMonthButton());
        container.append(this._createMonthBar(visibleMonths));
        container.append(this._createNextMonthButton());
        container.append(this._createNextYearButton());
        this._container.remove();
        this._dom.append(container);
        this._container = container;
    },

    _createMonthBar: function(visibleMonths) {
        var monthBar = $('<ul id="calendar_month_bar"/>');
        this._fillMonthItemsInMonthBar(visibleMonths, monthBar);
        return monthBar;
    },

    _updateMonthStatus: function(visibleMonthModels) {
        var me = this;
        visibleMonthModels.foreach(function(monthModel) {
            var yearMonth = monthModel.getYearMonth();
            var dayCompleteStatusBarData = me._getCompleteStatusBarData(monthModel);
            $.each($('li[year=' + yearMonth.year() + '][month=' + yearMonth.month() + '] ul li', me._dom), function(index, item) {
                $(item)
                        .removeClass()
                        .addClass(me._getCompletenessStatusClass(dayCompleteStatusBarData[index]));
            });

        });
    },

    _getCompleteStatusBarData: function(monthModel) {
        var dayCompleteStatus = monthModel.getDaysCompleteStatus();
        var dayCompleteStatusGroup = dayCompleteStatus.split(function(item, index) {
            return index % 3 == 0;
        });
        //handle 31 hg days month
        if (dayCompleteStatusGroup.length == 11) {
            dayCompleteStatusGroup[9].push(dayCompleteStatusGroup[10][0]);
        }
        var dayCompleteStatusBar = dayCompleteStatusGroup.select(function(daysStatus) {
            var firstFutureDay = daysStatus.findFirst(function(status) {
                return status == CompleteStatus.future
            });
            if (firstFutureDay) {
                return CompleteStatus.future;
            }
            var firstIncompleteDay = daysStatus.findFirst(function(status) {
                return status == CompleteStatus.incomplete
            });
            if (firstIncompleteDay) {
                return CompleteStatus.incomplete;
            }
            return CompleteStatus.complete;
        });
        return dayCompleteStatusBar;
    },

    ///TODO: wyh need to simplify this method
    _fillMonthItemsInMonthBar: function(visibleMonths, monthBar) {
        var me = this;
        var lastWrittenYear = null;
        var currentMonthSelectedClassName = 'selected';
        visibleMonths.foreach(function(monthModel) {
            var yearMonth = monthModel.getYearMonth();
            var monthIndex = yearMonth.month();
            var monthTitle = CalendarViewHeader.MONTH_SHORT_TITLES[monthIndex - 1];
            var monthItem = $('<span></span>').html(monthTitle).addClass("month");
            var completeStatusItem = $('<ul>').addClass('bar');
            for (var i = 0; i < 10; i++) {
                completeStatusItem.append($('<li>'));
            }

            var yearItem = "";
            if ((monthIndex == 1 || monthIndex == 12) && lastWrittenYear != yearMonth.year()) {
                lastWrittenYear = yearMonth.year();
                yearItem = $('<span></span>').html(yearMonth.year()).addClass("year");
            }
            
            var monthLiItem = $("<li></li>")
                    .append(yearItem)
                    .append(monthItem)
                    .append(completeStatusItem)
                    .attr("year", yearMonth.year())
                    .attr("month", yearMonth.month());
            if (me._headerStatus.selectedYearMonth.isSameWith(yearMonth)) {
                monthLiItem.append($('<div class="arrow"/>'));
                monthItem.addClass(currentMonthSelectedClassName);
            }
            monthLiItem.click(function() {
                me._headerStatus.selectedYearMonth = yearMonth;
                me.show();
            });

            monthBar.append(monthLiItem);
        });
    },

    _shiftVisibleMonth: function(months) {
        this._headerStatus.shiftMonths(months);
        this.show();
    },

    _shiftVisibleYear: function(years) {
        this._headerStatus.shiftYears(years);
        this.show();
    },

    _createPreviousYearButton: function() {
        var me = this;
        return this._createCalendarShiftButton("calendar-previous-year switch-year",
                function() {
                    me._shiftVisibleYear(-1);
                });
    },

    _createPreviousMonthButton: function() {
        var me = this;
        return this._createCalendarShiftButton("calendar-previous-month switch-month",
                function() {
                    me._shiftVisibleMonth(-1);
                });
    },

    _createNextMonthButton: function() {
        var me = this;
        return this._createCalendarShiftButton("calendar-next-month switch-month",
                function() {
                    me._shiftVisibleMonth(1);
                });
    },

    _createNextYearButton: function() {
        var me = this;
        return this._createCalendarShiftButton("calendar-next-year switch-year",
                function() {
                    me._shiftVisibleYear(1);
                });

    },

    _createCalendarShiftButton: function(buttonClass, clickCallback) {
        var container = $('<div class="calendar-month-scroll-bar"/>');
        var button = $('<button class="' + buttonClass + '"></button>');
        button.click(function() {
            clickCallback();
        });
        return container.append(button);
    },
    _getCompletenessStatusClass: function(completeStatus) {
        switch (completeStatus) {
            case CompleteStatus.complete:
                return 'complete';
            case CompleteStatus.incomplete:
                return "missing";
            default:
                return 'future';
        }
    }
};
CalendarViewHeader.MONTH_SHORT_TITLES = [
    i18n('LABEL_SHORT_MONTH_JAN'),
    i18n('LABEL_SHORT_MONTH_FEB'),
    i18n('LABEL_SHORT_MONTH_MAR'),
    i18n('LABEL_SHORT_MONTH_APR'),
    i18n('LABEL_SHORT_MONTH_MAY'),
    i18n('LABEL_SHORT_MONTH_JUN'),
    i18n('LABEL_SHORT_MONTH_JUL'),
    i18n('LABEL_SHORT_MONTH_AUG'),
    i18n('LABEL_SHORT_MONTH_SEP'),
    i18n('LABEL_SHORT_MONTH_OCT'),
    i18n('LABEL_SHORT_MONTH_NOV'),
    i18n('LABEL_SHORT_MONTH_DEC')
];
